#include "fig_exploding_manager.h"
#include "fig_exploding_collection.h"

#include "num/rand.h"


FIGExplodingManager&	FIGExplodingManager::Instance()
{
	static FIGExplodingManager	Inst;
	return Inst;
}

FIGExplodingManager::FIGExplodingManager()
{
	// initialize offscreen
	for(unsigned int i = 0; i < FIGExploding::EXPLODING_TYPES_COUNT; i++)
	{
		Spawn((FIGExploding::EXPLODING_TYPES)i, math::Vec2(1.5f,1.5f), 1.0f, 0);
	}
}

FIGExplodingManager::~FIGExplodingManager()
{

}

void		FIGExplodingManager::Render(const math::Vec2& Offset,float Scale)
{
	for(unsigned int i = 0; i < m_ExplodingCollections.size(); i++)
	{
		FIGExplodingCollection* pCol = m_ExplodingCollections[i];
		pCol->Render(Offset,Scale);
	}
}
	
void		FIGExplodingManager::RenderDebug(const math::Vec2& Offset,float Scale)
{
	for(unsigned int i = 0; i < m_ExplodingCollections.size(); i++)
	{
		FIGExplodingCollection* pCol = m_ExplodingCollections[i];
		pCol->RenderDebug(Offset,Scale);
	}
}


void		FIGExplodingManager::Tick(float dt)
{
	for(unsigned int i = 0; i < m_ExplodingCollections.size(); i++)
	{
		FIGExplodingCollection* pCol = m_ExplodingCollections[i];
		pCol->Tick(dt);
	}
}


void		FIGExplodingManager::Clear()
{
	for(unsigned int i = 0; i < m_ExplodingCollections.size(); i++)
	{
		FIGExplodingCollection* pCol = m_ExplodingCollections[i];
		pCol->Clear();
	}

	for( int i = (int)m_ExplodingCollections.size() - 1; i >= 0; i--)
	{
		FIGExplodingCollection* pCol = m_ExplodingCollections[i];
		UTIL_SAFE_DELETE(pCol);
	}
	m_ExplodingCollections.resize(0);
}

void		FIGExplodingManager::Spawn(FIGExploding::EXPLODING_TYPES Type, 
											const math::Vec2& Pos,
											float SizeScale,
											float Rotation,
											float MainDealy
											)
{
	const float BASE_SIZE = 0.025f;
	math::Vec2 DirVariation;
	math::Vec2 ExtraVariation;
	float Delay = 0;
	float SizeVariation = 0;
	float PreviousSizeScale = 1.0f;

	if(Type == FIGExploding::EXPLODING_GEMINI)
	{
		// we have to make multiple calls
		math::Vec2 LineDir;		
		int RandValue;

		int MainLoopCount = num::RAND32::Instance().RandInt(3,4);
		for(int j = 0; j < MainLoopCount; j++)
		{

			LineDir.x  = num::RAND32::Instance().RandFloat(0,1.0f);
			LineDir.y  = num::RAND32::Instance().RandFloat(0,1.0f);
			if(num::RAND32::Instance().RandInt(0,1) == 0)
				LineDir.x *= -1;
			if(num::RAND32::Instance().RandInt(0,1) == 0)
				LineDir.y *= -1;

			LineDir.Normalize();			
			LineDir.y *= GraphicsUtil::W2H;
			RandValue = num::RAND32::Instance().RandInt(6,10);
			
			Delay = 0;
			SizeVariation = 0.4f;
			
			DirVariation = math::Vec2(0,0);
			PreviousSizeScale = SizeScale + 2.0f;
			for(int i = 0; i < RandValue; i++)
			{
				ExtraVariation.x  = num::RAND32::Instance().RandFloat(0,1.0f);
				ExtraVariation.y  = num::RAND32::Instance().RandFloat(0,1.0f);
				if(num::RAND32::Instance().RandInt(0,1) == 0)
					ExtraVariation.x *= -1;
				if(num::RAND32::Instance().RandInt(0,1) == 0)
					ExtraVariation.y *= -1;

				ExtraVariation.Normalize();
				ExtraVariation.y *= GraphicsUtil::W2H;
				ExtraVariation *= 0.0125f;
				
				DirVariation += LineDir * ( BASE_SIZE * PreviousSizeScale);
				
				SpawnOnlyone(	Type, 
								Pos + DirVariation + ExtraVariation, 
								SizeScale + SizeVariation, 
								Rotation,
								MainDealy + Delay
								);
				Delay += 0.03f;
				SizeVariation -= num::RAND32::Instance().RandFloat(0.08f,0.1f);
				PreviousSizeScale = SizeScale + SizeVariation;


			}
		}

		// Center One
		SpawnOnlyone(	Type, Pos, SizeScale + 1.0f, Rotation, MainDealy + 0.07f);
		SpawnOnlyone(	Type, Pos, SizeScale + 1.5f, Rotation, MainDealy + 0.05f);
		SpawnOnlyone(	Type, Pos, SizeScale + 2.0f, Rotation, MainDealy );
		

	}
	else
	{
		SpawnOnlyone(Type, Pos, SizeScale, Rotation);

	}

	

			
}

void	FIGExplodingManager::SpawnOnlyone(FIGExploding::EXPLODING_TYPES Type, 
											const math::Vec2& Pos,
											float SizeScale,
											float Rotation,
											float Delay
											)
{
	bool Found = false;
	for( int i = (int)m_ExplodingCollections.size() - 1; i >= 0; i--)
	{
		FIGExplodingCollection* pCol = m_ExplodingCollections[i];
		if ( pCol->GetType() == Type)
		{
			pCol->Spawn(Pos, SizeScale, Rotation,Delay);
			Found = true;
		}		
	}

	if(!Found)
	{
		FIGExplodingCollection* pCol = new FIGExplodingCollection(Type);
		m_ExplodingCollections.push_back(pCol);
		pCol->Spawn(Pos, SizeScale, Rotation,Delay);
	}
}
